package com.dd.cloud.user.service.educationvisit.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.constants.TemplateConstants;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.utils.DateUtils;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.common.vo.PageReq;
import com.dd.cloud.user.entity.doctor.DoctorDetail;
import com.dd.cloud.user.entity.doctor.PatientMedCard;
import com.dd.cloud.user.entity.educationvisit.*;
import com.dd.cloud.user.entity.order.OrderPay;
import com.dd.cloud.user.entity.plat.PlatformLogin;
import com.dd.cloud.user.entity.pres.PresPrescription;
import com.dd.cloud.user.mapper.educationvisit.PatientEducationVisitMapper;
import com.dd.cloud.user.req.education.*;
import com.dd.cloud.user.req.template.TemplateData;
import com.dd.cloud.user.req.template.TemplateMessageGzhReq;
import com.dd.cloud.user.res.education.*;
import com.dd.cloud.user.service.doctor.IDoctorDetailService;
import com.dd.cloud.user.service.doctor.IPatientMedCardService;
import com.dd.cloud.user.service.educationvisit.*;
import com.dd.cloud.user.service.order.IOrderPayService;
import com.dd.cloud.user.service.patient.IPatientMedRankService;
import com.dd.cloud.user.service.plat.IPlatformLoginService;
import com.dd.cloud.user.service.plat.IPlatformWechatInfoService;
import com.dd.cloud.user.service.pres.IPresPrescriptionService;
import jodd.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 患教文章管理 服务实现类
 * </p>
 *
 * @author czg
 * @since 2024-01-15
 */
@Service
public class PatientEducationVisitServiceImpl extends ServiceImpl<PatientEducationVisitMapper, PatientEducationVisit> implements IPatientEducationVisitService {

    @Autowired
    private PatientEducationVisitMapper patientEducationArticleMapper;

    @Autowired
    private PatientEducationVisitMapper patientEducationVisitMapper;


    @Autowired
    private IPatientEducationArticleReadNumService patientEducationArticleReadNumService;

    @Autowired
    private IPatientEducationPushRecordService patientEducationPushRecordService;

    @Autowired
    private IPatientMedRankService patientMedRankService;

    @Autowired
    private IPlatformLoginService platformLoginService;

    @Autowired
    private IPlatformWechatInfoService platformWechatInfoService;


    @Autowired
    private IDoctorDetailService doctorDetailService;

    @Autowired
    private IPatientMedCardService patientMedCardService;

    @Autowired
    private IPatientEducationVisitTagService patientEducationVisitTagService;

    @Override
    public Page<PatientEducationVisit> queryPatientEducationArticlePage(PatientEducationArticleReq req) {
        if (StringUtil.isBlank(req.getStatus())) {
            req.setStatus("1,2,3");
        }
        Page<PatientEducationVisit> page = req.pagePojo();
        page = patientEducationArticleMapper.queryPatientEducationArticlePage(page, req);
        return page;
    }

    /**
     * 订单详情 查询患教文章/问卷(分页)
     *
     * @param req
     * @return
     */
    @Override
    public IPage<PatientEducationOrderRes> queryPatientEducationOrder(PatientEducationOrderReq req) {
        IPage<PatientEducationOrderRes> iPage = req.pagePojo();
        iPage = getBaseMapper().queryPatientEducationOrder(iPage, req);
        return iPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertPatientEducationArticle(PatientEducationArticleAddFrom from) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        PatientEducationVisit patientEducationArticle = new PatientEducationVisit();
        BeanUtils.copyProperties(from, patientEducationArticle);
        patientEducationArticle.setUpdateDate(LocalDateTime.now()).setCreateDate(LocalDateTime.now()).setOperName(loginInfo.getName());
        Boolean flag = this.save(patientEducationArticle);
        if (!flag) {
            throw new ZekeException("保存失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePatientEducationArticle(PatientEducationArticleUpdateFrom from) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Integer articleId = from.getArticleId();
        PatientEducationVisit patientEducationArticle = this.getById(articleId);
        if (patientEducationArticle == null) {
            throw new ZekeException("记录不存在");
        }
        BeanUtils.copyProperties(from, patientEducationArticle);
        patientEducationArticle.setUpdateDate(LocalDateTime.now()).setOperName(loginInfo.getName());
        Boolean flag = this.updateById(patientEducationArticle);
        if (!flag) {
            throw new ZekeException("更新失败");
        }
    }

    @Override
    public PatientEducationVisit queryPatientEducationArticleDetailById(Integer articleId) {
        PatientEducationVisit patientEducationArticle = this.getById(articleId);
        if (patientEducationArticle == null) {
            throw new ZekeException("记录为空");
        }
        Integer tagId = patientEducationArticle.getTagId();
        PatientEducationVisitTag tag = patientEducationVisitTagService.getById(tagId);
        if (tag != null) {
            patientEducationArticle.setTagName(tag.getTagName());
        }
        //查询总的阅读数
        LambdaQueryWrapper<PatientEducationArticleReadNum> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PatientEducationArticleReadNum::getArticleId, articleId).eq(PatientEducationArticleReadNum::getStatus, 1);
        Integer readCount = patientEducationArticleReadNumService.count(queryWrapper);
        patientEducationArticle.setReadNum(readCount);
        QueryWrapper<PatientEducationVisitPushRecord> qw = new QueryWrapper<>();
        qw.lambda().eq(PatientEducationVisitPushRecord::getEducationVisitId, articleId);
        PatientEducationVisitPushRecord patientEducationVisitPushRecord = patientEducationPushRecordService.getOne(qw);
        if (patientEducationVisitPushRecord != null) {
            patientEducationArticle.setReason(patientEducationVisitPushRecord.getReason());
            patientEducationArticle.setTsStatus(patientEducationVisitPushRecord.getPushStatus());
        }
        return patientEducationArticle;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePatientEducationArticleStatus(Integer articleId, Integer status) {
        PatientEducationVisit patientEducationArticle = this.getById(articleId);
        if (patientEducationArticle == null) {
            throw new ZekeException("记录不存在");
        }
        patientEducationArticle.setStatus(status);
        Boolean flag = this.updateById(patientEducationArticle);
        if (!flag) {
            throw new ZekeException("修改状态失败");
        }
    }

    @Override
    public void updatePatientEducationArticleReadCount(Integer articleId) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        LambdaQueryWrapper<PatientEducationArticleReadNum> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PatientEducationArticleReadNum::getArticleId, articleId).eq(PatientEducationArticleReadNum::getUserId, loginInfo.getId()).eq(PatientEducationArticleReadNum::getUserType, loginInfo.getType()).eq(PatientEducationArticleReadNum::getStatus, 1);
        Integer count = patientEducationArticleReadNumService.count(queryWrapper);
        if (count > 0) {
            return;
        }
        PatientEducationArticleReadNum patientEducationArticleReadNum = new PatientEducationArticleReadNum();
        patientEducationArticleReadNum.setArticleId(articleId).setStatus(1).setCreateDate(LocalDateTime.now()).setUserId(loginInfo.getId()).setUserType(loginInfo.getType());
        Boolean flag = patientEducationArticleReadNumService.save(patientEducationArticleReadNum);
        if (!flag) {
            throw new ZekeException("保存失败");
        }
    }

    @Override
    public Page<PatientEducationRecordRes> queryPatientEducationPushRecordPage(PatientEducationPushRecordReq req) {
        Page<PatientEducationRecordRes> page = req.pagePojo();
        page = patientEducationArticleMapper.queryPatientEducationPushRecordPage(page, req);
        return page;
    }

    @Autowired
    IPresPrescriptionService presPrescriptionService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pushPatientEducationPushRecord(Integer id) {
        PatientEducationVisitPushRecord record = patientEducationPushRecordService.getById(id);
        if (record == null) {
            throw new ZekeException("记录不存在");
        }
        String tencode = record.getTencode();
        PresPrescription presPrescription = presPrescriptionService.getById(tencode);
        if (presPrescription == null) {
            return;
        }
        Integer articleId = record.getEducationVisitId();
        PatientEducationVisit patientEducationVisit = patientEducationArticleMapper.selectById(articleId);
        if (patientEducationVisit == null) {
            throw new ZekeException("文章不存在");
        }
        //发送模板消息
        Boolean flag = sendTemplateToUser(record.getMedId(), record.getType(), patientEducationVisit.getUrl(), record.getTencode());
        if (flag) {
            record.setPushStatus(1);
        }
        record.setSendDate(LocalDateTime.now());
        boolean flag1 = patientEducationPushRecordService.updateById(record);
        if (!flag1) {
            throw new ZekeException("更新失败");
        }
    }


    @Override
    public Page<PatientEducationUseDrugRes> queryUserDrugRecordPage(PatientEducationVisitReq req) {
        Page<PatientEducationUseDrugRes> page = req.pagePojo();
        page = patientEducationVisitMapper.queryUserDrugRecordPage(page, req);
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void writeQuestionnaire(String content, Integer id) {
        PatientEducationVisitPushRecord patientEducationVisitPushRecord = patientEducationPushRecordService.getById(id);
        if (patientEducationVisitPushRecord == null) {
            throw new ZekeException("记录不存在");
        }
        patientEducationVisitPushRecord.setContent(content).setIsWrite(1).setSubmitDate(LocalDateTime.now());
        Boolean flag = patientEducationPushRecordService.updateById(patientEducationVisitPushRecord);
        if (!flag) {
            throw new ZekeException("填写问卷失败");
        }
    }

    @Autowired
    private IPatientVisitFeedBackService patientVisitFeedBackService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void writeQuestionnaireFeel(String feel, String reply, Integer id) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Integer userId = loginInfo.getId();
        PatientVisitFeedBack patientVisitFeedBack = new PatientVisitFeedBack();
        patientVisitFeedBack.setPushId(id).setStatus(1).setCreateDate(LocalDateTime.now()).setReply(reply).setFeel(feel).setUserId(userId);
        Boolean flag = patientVisitFeedBackService.save(patientVisitFeedBack);
        if (!flag) {
            throw new ZekeException("提交随访内容失败");
        }
    }

    @Override
    public PatientEducationVisitPushRecord queryPatientEducationVisitPushRecordDetail(Integer id) {
        return patientEducationPushRecordService.getById(id);
    }

    @Override
    public Page<PatientEducationRecordRes> queryCloudConsultingRoomPage(PatientEducationPushRecordReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Integer doctorId = loginInfo.getId();
        req.setDoctorId(doctorId);
        Page<PatientEducationRecordRes> page = req.pagePojo();
        page = patientEducationVisitMapper.queryCloudConsultingRoomPage(page, req);
        return page;
    }

    @Override
    public Boolean queryIsSubmitFeedBack(Integer id) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        LambdaQueryWrapper<PatientVisitFeedBack> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PatientVisitFeedBack::getUserId, loginInfo.getId()).eq(PatientVisitFeedBack::getStatus, 1).eq(PatientVisitFeedBack::getPushId, id);
        Integer count = patientVisitFeedBackService.count(queryWrapper);
        return count > 0;
    }


    @Override
    public void pushTemplateToPatient(Integer id, Integer type, String medId, String orderNo) {
        PatientEducationVisit patientEducationVisit = patientEducationArticleMapper.selectById(id);
        if (patientEducationVisit == null) {
            throw new ZekeException("文章不存在");
        }
        OrderPay orderPay = orderPayService.getById(orderNo);
        if (orderPay == null) {
            return;
        }
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Boolean flag = sendTemplateToUser(medId, type, patientEducationVisit.getUrl(), orderPay.getServerNo());
        PatientEducationVisitPushRecord record = new PatientEducationVisitPushRecord();
        record.setEducationVisitId(id).setTitle(patientEducationVisit.getTitle()).setMedId(medId).setCreateDate(LocalDateTime.now()).setStatus(1).setSendDate(LocalDateTime.now()).setSendName(loginInfo.getName()).setSendId(loginInfo.getId()).setContent(patientEducationVisit.getContent()).setSendType(loginInfo.getType()).setOrderNo(orderNo).setTencode(orderPay.getServerNo()).setType(type);
        if (flag) {
            record.setPushStatus(1);
        } else {
            record.setPushStatus(2);
            record.setReason("未关注公众号");
        }
        boolean flag1 = patientEducationPushRecordService.save(record);
        if (!flag1) {
            throw new ZekeException("保存失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createPatientEducationVisitRecordSystem(PatientEducationVisitRecordSystemCreateReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        req.setType(3);
        PatientEducationVisitPushRecord pevpr = new PatientEducationVisitPushRecord();
        BeanUtils.copyProperties(req, pevpr);
        pevpr.setSendId(loginInfo.getId());
        pevpr.setSendType(loginInfo.getType());
        pevpr.setSendName(loginInfo.getName());
        pevpr.setSendDate(LocalDateTime.now());
        pevpr.setCreateDate(LocalDateTime.now());
        pevpr.setSubmitDate(LocalDateTime.now());
        pevpr.setStatus(1);
        boolean flag = patientEducationPushRecordService.save(pevpr);
        if (!flag) {
            throw new ZekeException("提交电话随访内容失败");
        }
    }

    @Override
    public IPage<PatientEducationRecordOrderRes> queryPatientEducationRecordOrder(PatientEducationRecordOrderReq req) {
        if (StringUtils.isBlank(req.getType())) {
            req.setType("1");
        }
        IPage<PatientEducationRecordOrderRes> iPage = req.pagePojo();
        iPage = getBaseMapper().queryPatientEducationRecordOrder(iPage, req);
        for (PatientEducationRecordOrderRes item : iPage.getRecords()) {
            item.setDate(item.getSendDate().toLocalDate());
        }
        return iPage;
    }

    /**
     * 定时发送用药提醒
     */
    @Override
    public void taskPatientDrugTip() {
        PageReq pageReq = new PageReq();
        pageReq.setPage(1);
        pageReq.setPageSize(100);
        IPage<PatientPresDrugTipRes> iPage;
        do {
            iPage = pageReq.pagePojo();
            iPage = getBaseMapper().queryPatientPresDrugTip(iPage);
            for (PatientPresDrugTipRes item : iPage.getRecords()) {
                Boolean flag = sendTemplateToUser(item.getMedId(), 4, "", item.getTencode());
                PatientEducationVisitPushRecord record = new PatientEducationVisitPushRecord();
                record.setMedId(item.getMedId()).setCreateDate(LocalDateTime.now()).setStatus(1).setSendDate(LocalDateTime.now()).setSendName("系统").setSendId(0).setSendType(0).setOrderNo(item.getOrderNo()).setTencode(item.getTencode()).setType(4);
                if (flag) {
                    record.setPushStatus(1);
                } else {
                    record.setPushStatus(2);
                    record.setReason("未关注公众号");
                }
                patientEducationPushRecordService.save(record);
            }
            pageReq.setPage(pageReq.getPage() + 1);
        } while (iPage.getPages() > pageReq.getPage());

    }

    /**
     * 重新推送用药提醒
     *
     * @param id
     * @param medId
     * @param tencode
     */
    @Override
    public void againPushDrugTemplateToPatient(Integer id, String medId, String tencode) {
        Boolean flag = sendTemplateToUser(medId, 4, "", tencode);
        PatientEducationVisitPushRecord record = patientEducationPushRecordService.getById(id);
        record.setSendDate(LocalDateTime.now());
        if (flag) {
            record.setPushStatus(1);
        } else {
            record.setPushStatus(2);
            record.setReason("未关注公众号");
        }
        patientEducationPushRecordService.updateById(record);
    }

    @Autowired
    private IOrderPayService orderPayService;

    public Boolean sendTemplateToUser(String medId, Integer type, String url, String tencode) {
        PresPrescription presPrescription = presPrescriptionService.getById(tencode);
        if (presPrescription == null) {
            return false;
        }
        Integer doctorId = presPrescription.getDoctorId();
        LambdaQueryWrapper<DoctorDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DoctorDetail::getDoctorId, doctorId).eq(DoctorDetail::getStatus, 1);
        DoctorDetail doctorDetail = doctorDetailService.getOne(queryWrapper);
        if (doctorDetail == null) {
            return false;
        }
        List<Integer> patientIds = patientMedRankService.queryPatientIdListByMedId(medId);
        LambdaQueryWrapper<PatientMedCard> qw = new LambdaQueryWrapper<>();
        qw.eq(PatientMedCard::getMedId, medId).eq(PatientMedCard::getStatus, 1);
        PatientMedCard patientMedCard = patientMedCardService.getOne(qw);
        if (patientMedCard == null) {
            return false;
        }
        for (Integer patientId : patientIds) {
            String openId = getUserOpenId(patientId);
            if (StringUtils.isBlank(openId)) {
                continue;
            }
            TemplateMessageGzhReq templateMessageGzhReq = new TemplateMessageGzhReq();
            templateMessageGzhReq.setToUser(openId);
            //发送模板消息
            Map<String, TemplateData> map = new HashMap<>();
            if (type == 1) {
                templateMessageGzhReq.setTemplateId(TemplateConstants.TemplateType.PATIENT_EDUCATION);
                map.put("thing1", new TemplateData(doctorDetail.getName()));
                //TODO 结束时间
                map.put("time3", new TemplateData());
                map.put("thing4", new TemplateData(patientMedCard.getName()));
                map.put("const5", new TemplateData("您的问诊完成，点击查看内容"));
            } else if (type == 2) {
                templateMessageGzhReq.setTemplateId(TemplateConstants.TemplateType.PATIENT_VISIT);
                map.put("thing2", new TemplateData(doctorDetail.getName()));
                //TODO 结束时间
                map.put("thing3", new TemplateData(patientMedCard.getName()));
                map.put("const4", new TemplateData("咨询已结束，邀请您填写问卷"));
            } else if (type == 4) {
                templateMessageGzhReq.setTemplateId(TemplateConstants.TemplateType.PATIENT_DRUG_TIP);
                String name = patientMedCard.getName();
                if (name.length() == 2) {
                    name = name.charAt(0) + "*";
                } else {
                    name = name.charAt(0) + "*" + name.substring(name.length() - 1);
                }
                map.put("thing2", new TemplateData(name));
                map.put("time1", new TemplateData(DateUtils.DTF_YMD.format(LocalDate.now())));
                url = "https://admin.dadaotcm.com/dadaomos/pages/Medicationreminder/Medicationreminder?dayDose=" + presPrescription.getDayDose() + "&doseNum=" + presPrescription.getDoseNum() + "&drugDose=" + presPrescription.getDrugDose() + "&takemethod=" + presPrescription.getUseDrugWay() + "&advice=" + presPrescription.getAdvice();
            }
            templateMessageGzhReq.setData(map);
            templateMessageGzhReq.setUrl(url);
            return platformWechatInfoService.sendTemplateMessageGzh(templateMessageGzhReq, platformLoginService.getPatientUserGzhAccessToken());
        }
        return false;
    }

    public String getUserOpenId(Integer userId) {
        LambdaQueryWrapper<PlatformLogin> plWrapper = new LambdaQueryWrapper<>();
        plWrapper.eq(PlatformLogin::getUserId, userId).eq(PlatformLogin::getUserType, LoginInfo.UserType.PATIENT);
        PlatformLogin platformLogin = platformLoginService.getOne(plWrapper);
        if (platformLogin != null) {
            return platformLogin.getPlatId();
        }
        return "";
    }
}
